﻿using Microsoft.Extensions.Caching.Distributed;

namespace Net8.Project.Common.Caches
{
    /// <summary>
    /// 缓存服务接口，基于 IDistributedCache 封装，提供常用缓存操作方法。
    /// 既可以用内存实现，也可以用 Redis 实现
    /// </summary>
    public interface ICaching
    {
        /// <summary>
        /// 获取底层分布式缓存实例。
        /// </summary>
        IDistributedCache Cache { get; }

        /// <summary>
        /// 添加缓存键到缓存键集合。
        /// </summary>
        /// <param name="cacheKey">缓存键</param>
        void AddCacheKey(string cacheKey);

        /// <summary>
        /// 异步添加缓存键到缓存键集合。
        /// </summary>
        /// <param name="cacheKey">缓存键</param>
        Task AddCacheKeyAsync(string cacheKey);

        /// <summary>
        /// 根据模式批量删除缓存（支持通配符）。
        /// </summary>
        /// <param name="pattern">匹配模式</param>
        void DelByPattern(string pattern);

        /// <summary>
        /// 异步根据模式批量删除缓存（支持通配符）。
        /// </summary>
        /// <param name="pattern">匹配模式</param>
        Task DelByPatternAsync(string pattern);

        /// <summary>
        /// 删除指定缓存键。
        /// </summary>
        /// <param name="cacheKey">缓存键</param>
        void DelCacheKey(string cacheKey);

        /// <summary>
        /// 异步删除指定缓存键。
        /// </summary>
        /// <param name="cacheKey">缓存键</param>
        Task DelCacheKeyAsync(string cacheKey);

        /// <summary>
        /// 判断缓存键是否存在。
        /// </summary>
        /// <param name="cacheKey">缓存键</param>
        /// <returns>是否存在</returns>
        bool Exists(string cacheKey);

        /// <summary>
        /// 异步判断缓存键是否存在。
        /// </summary>
        /// <param name="cacheKey">缓存键</param>
        /// <returns>是否存在</returns>
        Task<bool> ExistsAsync(string cacheKey);

        /// <summary>
        /// 获取所有缓存键集合。
        /// </summary>
        /// <returns>缓存键列表</returns>
        List<string> GetAllCacheKeys();

        /// <summary>
        /// 异步获取所有缓存键集合。
        /// </summary>
        /// <returns>缓存键列表</returns>
        Task<List<string>> GetAllCacheKeysAsync();

        /// <summary>
        /// 获取指定类型的缓存值。
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="cacheKey">缓存键</param>
        /// <returns>缓存值</returns>
        T Get<T>(string cacheKey);

        /// <summary>
        /// 异步获取指定类型的缓存值。
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="cacheKey">缓存键</param>
        /// <returns>缓存值</returns>
        Task<T> GetAsync<T>(string cacheKey);

        /// <summary>
        /// 获取指定类型的缓存值（运行时类型）。
        /// </summary>
        /// <param name="type">值类型</param>
        /// <param name="cacheKey">缓存键</param>
        /// <returns>缓存值</returns>
        object Get(Type type, string cacheKey);

        /// <summary>
        /// 异步获取指定类型的缓存值（运行时类型）。
        /// </summary>
        /// <param name="type">值类型</param>
        /// <param name="cacheKey">缓存键</param>
        /// <returns>缓存值</returns>
        Task<object> GetAsync(Type type, string cacheKey);

        /// <summary>
        /// 获取字符串类型的缓存值。
        /// </summary>
        /// <param name="cacheKey">缓存键</param>
        /// <returns>缓存字符串</returns>
        string GetString(string cacheKey);

        /// <summary>
        /// 异步获取字符串类型的缓存值。
        /// </summary>
        /// <param name="cacheKey">缓存键</param>
        /// <returns>缓存字符串</returns>
        Task<string> GetStringAsync(string cacheKey);

        /// <summary>
        /// 移除指定缓存键。
        /// </summary>
        /// <param name="key">缓存键</param>
        void Remove(string key);

        /// <summary>
        /// 异步移除指定缓存键。
        /// </summary>
        /// <param name="key">缓存键</param>
        Task RemoveAsync(string key);

        /// <summary>
        /// 移除所有缓存。
        /// </summary>
        void RemoveAll();

        /// <summary>
        /// 异步移除所有缓存。
        /// </summary>
        Task RemoveAllAsync();

        /// <summary>
        /// 设置缓存值（可指定过期时间）。
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="cacheKey">缓存键</param>
        /// <param name="value">缓存值</param>
        /// <param name="expire">过期时间（可选）</param>
        void Set<T>(string cacheKey, T value, TimeSpan? expire = null);

        /// <summary>
        /// 异步设置缓存值（不过期）。
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="cacheKey">缓存键</param>
        /// <param name="value">缓存值</param>
        Task SetAsync<T>(string cacheKey, T value);

        /// <summary>
        /// 异步设置缓存值（指定过期时间）。
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="cacheKey">缓存键</param>
        /// <param name="value">缓存值</param>
        /// <param name="expire">过期时间</param>
        Task SetAsync<T>(string cacheKey, T value, TimeSpan expire);

        /// <summary>
        /// 设置永久缓存值（不过期）。
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="cacheKey">缓存键</param>
        /// <param name="value">缓存值</param>
        void SetPermanent<T>(string cacheKey, T value);

        /// <summary>
        /// 异步设置永久缓存值（不过期）。
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="cacheKey">缓存键</param>
        /// <param name="value">缓存值</param>
        Task SetPermanentAsync<T>(string cacheKey, T value);

        /// <summary>
        /// 设置字符串类型的缓存值（可指定过期时间）。
        /// </summary>
        /// <param name="cacheKey">缓存键</param>
        /// <param name="value">缓存字符串</param>
        /// <param name="expire">过期时间（可选）</param>
        void SetString(string cacheKey, string value, TimeSpan? expire = null);

        /// <summary>
        /// 异步设置字符串类型的缓存值（不过期）。
        /// </summary>
        /// <param name="cacheKey">缓存键</param>
        /// <param name="value">缓存字符串</param>
        Task SetStringAsync(string cacheKey, string value);

        /// <summary>
        /// 异步设置字符串类型的缓存值（指定过期时间）。
        /// </summary>
        /// <param name="cacheKey">缓存键</param>
        /// <param name="value">缓存字符串</param>
        /// <param name="expire">过期时间</param>
        Task SetStringAsync(string cacheKey, string value, TimeSpan expire);

        /// <summary>
        /// 异步根据父键批量删除缓存。
        /// </summary>
        /// <param name="key">父键</param>
        Task DelByParentKeyAsync(string key);
    }
}
